#!/bin/sh
# -*- mode: shell-script; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
#
# Copyright (C) 2012, 2013, 2016 O.S. Systems Software LTDA.
# Authored-by:  Otavio Salvador <otavio@ossystems.com.br>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Add options for the script
# Copyright (C) 2013 Freescale Semiconductor, Inc.

PROGNAME="setup-env"

if [ -z "$ZSH_NAME" ] && echo "$0" | grep -q "$PROGNAME"; then
    echo "ERROR: This script needs to be sourced."
    SCRIPT_PATH=`readlink -f $0`
    if [ "`readlink $SHELL`" = "dash" ];then
        echo "Try run command \"set -- -h; . $SCRIPT_PATH\" to get help."
    else
        echo "Try run command \". $SCRIPT_PATH -h\" to get help."
    fi
    unset SCRIPT_PATH PROGNAME
    exit
else
    if [ -n "$BASH_SOURCE" ]; then
        ROOTDIR="`readlink -f $BASH_SOURCE | xargs dirname`"
    elif [ -n "$ZSH_NAME" ]; then
        ROOTDIR="`readlink -f $0 | xargs dirname`"
    else
        ROOTDIR="`readlink -f $PWD | xargs dirname`"
    fi
    if ! [ -e "$ROOTDIR/$PROGNAME" ];then
        echo "Go to where $PROGNAME locates, then run: . $PROGNAME <args>"
        unset ROOTDIR PROGNAME
        return
    fi
fi

# Check if current user is root
if [ "$(whoami)" = "root" ]; then
    echo "ERROR: Do not use the BSP as root. Exiting..."
    unset ROOTDIR PROGNAME
    return
fi

OEROOTDIR=${ROOTDIR}/sources/poky
if [ -e ${ROOTDIR}/sources/oe-core ]; then
    OEROOTDIR=${ROOTDIR}/sources/oe-core
fi
FSLROOTDIR=${ROOTDIR}/sources/meta-freescale
PROJECT_DIR=${ROOTDIR}/build_${MACHINE}

prompt_message () {
local i=''
echo "Welcome to Freescale QorIQ SDK (Reference Distro)

The Yocto Project has extensive documentation about OE including a
reference manual which can be found at:
    http://yoctoproject.org/documentation

For more information about OpenEmbedded see their website:
    http://www.openembedded.org/

You can now run 'bitbake <target>'
    fsl-image-networking
    fsl-image-networking-full
"
    echo "To return to this build environment later please run:"
    echo "    . $PROJECT_DIR/SOURCE_THIS"
}

clean_up()
{
   unset PROGNAME ROOTDIR OEROOTDIR FSLROOTDIR PROJECT_DIR \
         EULA EULA_FILE LAYER_LIST MACHINE FSLDISTRO EXTRAROOTDIR \
         OLD_OPTIND CPUS JOBS THREADS DOWNLOADS CACHES DISTRO \
         setup_flag setup_h setup_j setup_t setup_g setup_l setup_builddir \
         setup_download setup_sstate setup_error layer append_layer \
         valid_machine valid_num
   unset -f usage prompt_message
}

usage() {
    echo "Usage: . $PROGNAME -m <machine>"

    echo -e "\n    Supported machines:
    `find ${ROOTDIR}/sources/meta-freescale*/conf/machine \
        ${ROOTDIR}/sources/meta-fsl*/*/*/conf/machine \
	${ROOTDIR}/sources/meta-qoriq/conf/machine \
        -name *.conf 2>/dev/null \
        |egrep "/(mpc|b4|bsc|c29|p1|p2|p3|p4|p5|t1|t2|t4|ls|lx).*conf$" |sort \
        |xargs echo |sed -e 's,[^ ]*/,,g;s,.conf,,g'`
"

    echo "    Optional parameters:
    * [-m machine]: the target machine to be built.
    * [-j jobs]:    number of jobs for make to spawn during the compilation stage.
    * [-t tasks]:   number of BitBake tasks that can be issued in parallel.
    * [-b path]:    non-default path of project build folder.
    * [-d path]:    non-default path of DL_DIR (downloaded source)
    * [-c path]:    non-default path of SSTATE_DIR (shared state Cache)
    * [-h]:         help
"
    if [ "`readlink $SHELL`" = "dash" ];then
        echo "
    You are using dash which does not pass args when being sourced.
    To workaround this limitation, use \"set -- args\" prior to
    sourcing this script. For exmaple:
        \$ set -- -m ls1088ardb -j 3 -t 2
        \$ . $ROOTDIR/$PROGNAME
"
    fi
}

# parse the parameters
OLD_OPTIND=$OPTIND
while getopts "m:j:t:b:d:c:h" setup_flag
do
    case $setup_flag in
        m) MACHINE="$OPTARG";
           ;;
        j) setup_j="$OPTARG";
           ;;
        t) setup_t="$OPTARG";
           ;;
        b) setup_builddir="$OPTARG";
           ;;
        d) setup_download="$OPTARG";
           ;;
        c) setup_sstate="$OPTARG";
           ;;
        h) setup_h='true';
           ;;
        ?) setup_error='true';
           ;;
    esac
done
OPTIND=$OLD_OPTIND

# check the "-h" and other not supported options
if test $setup_error || test $setup_h; then
    usage && clean_up && return
fi

# Check the machine type specified
valid_machine=false
if [ -n "${MACHINE}" ];then
    valid_num=`find ${ROOTDIR}/sources/meta-freescale*/conf/machine \
        ${ROOTDIR}/sources/meta-fsl*/*/*/conf/machine \
	${ROOTDIR}/sources/meta-qoriq/conf/machine \
        -name ${MACHINE}.conf 2>/dev/null |wc -l`
    if [ "1" -lt "$valid_num" ];then
        echo "ERROR: possible error may occur due to duplicate ${MACHINE}.conf exist:"
        find ${ROOTDIR}/sources/meta-freescale*/conf/machine \
            ${ROOTDIR}/sources/meta-fsl*/*/*/conf/machine \
	    ${ROOTDIR}/sources/meta-qoriq/conf/machine \ 
            -name ${MACHINE}.conf 2>/dev/null
        echo "Please remove the useless layer under ${ROOTDIR}/sources"
        clean_up && return
    elif [ "0" = "$valid_num" ];then
        echo "$MACHINE is not supported by this build setup."
        usage && clean_up && return
    fi
else
    usage && clean_up && return
fi

echo "Configuring for ${MACHINE} ..."
LAYER_LIST=" \
    meta-openembedded/meta-oe \
    meta-openembedded/meta-multimedia \
    meta-openembedded/meta-python \
    meta-openembedded/meta-networking \
    meta-openembedded/meta-gnome \
    meta-openembedded/meta-filesystems \
    meta-openembedded/meta-webserver \
    meta-openembedded/meta-perl \
    meta-virtualization \
    meta-cloud-services \
    meta-security \
    meta-freescale \
    meta-freescale-distro \
    meta-nxp-common \
    meta-qoriq \
"
EULA_FILE="$FSLROOTDIR/EULA"

DISTRO="fsl-qoriq"

# set default jobs and threads
CPUS=`grep -c processor /proc/cpuinfo`
JOBS="4"
THREADS="4"

# check optional jobs and threads
if echo "$setup_j" | egrep -q "^[0-9]+$"; then
    JOBS=$setup_j
fi
if echo "$setup_t" | egrep -q "^[0-9]+$"; then
    THREADS=$setup_t
fi

# set project folder location and name
if [ -n "$setup_builddir" ]; then
    if echo $setup_builddir |grep -q ^/;then
        PROJECT_DIR="${setup_builddir}"
    else
        PROJECT_DIR="`pwd`/${setup_builddir}"
    fi
else
    PROJECT_DIR=${ROOTDIR}/build_${MACHINE}
fi
mkdir -p $PROJECT_DIR

if [ -n "$setup_download" ]; then
    if echo $setup_download |grep -q ^/;then
        DOWNLOADS="${setup_download}"
    else
        DOWNLOADS="`pwd`/${setup_download}"
    fi
else
    DOWNLOADS="$ROOTDIR/downloads"
fi
mkdir -p $DOWNLOADS
DOWNLOADS=`readlink -f "$DOWNLOADS"`

if [ -n "$setup_sstate" ]; then
    if echo $setup_sstate |grep -q ^/;then
        CACHES="${setup_sstate}"
    else
        CACHES="`pwd`/${setup_sstate}"
    fi
else
    CACHES="$ROOTDIR/sstate-cache"
fi
mkdir -p $CACHES
CACHES=`readlink -f "$CACHES"`

# check if project folder was created before
if [ -e "$PROJECT_DIR/SOURCE_THIS" ]; then
    echo "$PROJECT_DIR was created before."
    . $PROJECT_DIR/SOURCE_THIS
    echo "Nothing is changed."
    clean_up && return
fi

# source oe-init-build-env to init build env
cd $OEROOTDIR
set -- $PROJECT_DIR
. ./oe-init-build-env > /dev/null

# if conf/local.conf not generated, no need to go further
if [ ! -e conf/local.conf ]; then
    echo "ERROR: the local.conf is not created, Exit ..."
    clean_up && cd $ROOTDIR && return
fi

# Remove comment lines and empty lines
sed -i -e '/^#.*/d' -e '/^$/d' conf/local.conf

# Change settings according to the environment
sed -e "s,MACHINE ??=.*,MACHINE ??= '$MACHINE',g" \
        -e "s,DISTRO ?=.*,DISTRO ?= '$DISTRO',g" \
        -i conf/local.conf

# Clean up PATH, because if it includes tokens to current directories somehow,
# wrong binaries can be used instead of the expected ones during task execution
export PATH="`echo $PATH | sed 's/\(:.\|:\)*:/:/g;s/^.\?://;s/:.\?$//'`"

# add layers
for layer in $(eval echo $LAYER_LIST); do
    append_layer=""
    if [ -e ${ROOTDIR}/sources/${layer} ]; then
        append_layer="${ROOTDIR}/sources/${layer}"
    fi
    if [ -n "${append_layer}" ]; then
        append_layer=`readlink -f $append_layer`
        awk '/  "$/ && !x {print "'"  ${append_layer}"' \\"; x=1} 1' \
            conf/bblayers.conf > conf/bblayers.conf~
        mv conf/bblayers.conf~ conf/bblayers.conf
    fi
done

cat >> conf/local.conf <<-EOF

# Parallelism Options
BB_NUMBER_THREADS = "$THREADS"
PARALLEL_MAKE = "-j $JOBS"
DL_DIR = "$DOWNLOADS"
SSTATE_DIR = "$CACHES"
INITRAMFS_IMAGE = "core-image-minimal"
EOF

if expr "$MACHINE" : lx216;then
   cat >>conf/local.conf <<-EOF

# Specify DISTRO_FEATURES to select Chain of Trust(COT) for Trusted Board Boot
# feature in ATF. Two options:
# 1. secure: generate COT by cst from NXP
# 2. arm-cot: generate COT by cert_create from ATF
# uncomment below line to choose one:
#DISTRO_FEATURES_append = " secure"

EOF
fi

if [ "$MACHINE" = "ls1028ardb" ]; then
   cat >>conf/local.conf <<-EOF
# uncomment the below lines when building fsl-image-multimedia-full
#DISTRO_FEATURES_remove = " x11"
#PREFERRED_VERSION_weston = "9.0.0.imx"
#PREFERRED_VERSION_wayland-protocols = "1.20.imx"
#PREFERRED_VERSION_libdrm = "2.4.102.imx"
#PREFERRED_PROVIDER_virtual/libgl  = "imx-gpu-viv"
#PREFERRED_PROVIDER_virtual/libgles1 = "imx-gpu-viv"
#PREFERRED_PROVIDER_virtual/libgles2 = "imx-gpu-viv"
#PREFERRED_PROVIDER_virtual/egl      = "imx-gpu-viv"

# Some gstream plugins require "commercial" be set in LICENSE_FLAGS_WHITELIST
# For exmaple, gstreamer1.0-plugins-ugly-asf/gstreamer1.0-libav
# uncomment the below one line to include them into fsl-image-multimedia-full
#LICENSE_FLAGS_WHITELIST_append = " commercial"

EOF
fi

for s in $HOME/.oe $HOME/.yocto; do
    if [ -e $s/site.conf ]; then
        echo "Linking $s/site.conf to conf/site.conf"
        ln -s $s/site.conf conf
    fi
done

if echo "$MACHINE" |egrep -q "^(b4|p5|t1|t2|t4)"; then
    # disable prelink (for multilib scenario) for now
    sed -i s/image-mklibs.image-prelink/image-mklibs/g conf/local.conf
fi

# Handle EULA setting
if [ -z "$EULA" ] && ! grep -q '^ACCEPT_FSL_EULA\s*=' conf/local.conf; then
    EULA='ask'
fi

if [ "$EULA" = "ask" ]; then
    cat <<EOF

Proprietary and third party software is subject to agreement and compliance
with, Freescale's End User License Agreement. To have the right to use these
binaries in your images, you must read and accept the following terms.  If
there are conflicting terms embedded in the software, the terms embedded in
the Software will control.

In all cases,  open source software is licensed under the terms of the
applicable open source license(s), such as the BSD License, Apache License or
the GNU Lesser General Public License.  Your use of the open source software
is subject to the terms of each applicable license.  You must agree to the
terms of each applicable license, or you cannot use the open source software.

EOF

    sleep 5

    more -d $EULA_FILE
    echo
    while [ "$EULA" = "ask" ]; do
        echo -n "Do you accept the EULA you just read? (y/n) "
        read REPLY
        case "$REPLY" in
            y|Y)
            echo "EULA has been accepted."
            EULA="1"
            ;;
            n|N)
            echo "EULA has not been accepted."
            EULA="0"
            ;;
        esac
    done
fi

if grep -q '^ACCEPT_FSL_EULA\s*=' conf/local.conf; then
    sed -i "s/^#*ACCEPT_FSL_EULA\s*=.*/ACCEPT_FSL_EULA = \"$EULA\"/g" conf/local.conf
else
    echo "ACCEPT_FSL_EULA = \"$EULA\"" >> conf/local.conf
fi

# make a SOURCE_THIS file
if [ ! -e SOURCE_THIS ]; then
    echo "#!/bin/sh" >> SOURCE_THIS
    echo "cd $OEROOTDIR" >> SOURCE_THIS
    echo "set -- $PROJECT_DIR" >> SOURCE_THIS
    echo ". ./oe-init-build-env > /dev/null" >> SOURCE_THIS
    echo "echo \"Back to build project $PROJECT_DIR.\"" >> SOURCE_THIS
fi

prompt_message
cd $PROJECT_DIR
clean_up
